﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using SharpSvn;

namespace EyeballLib
{
    public delegate void CommitFinishedEventHandler(object sender, EventArgs e);

    public class SvnCrawler
    {
        public Repository RepositoryInfo { get; private set; }
        private DataClassesDataContext DataSource { get; set; }

        public event CommitFinishedEventHandler CommitFinished;

        public long LatestRevision { get; set; }
        public string Progress
        {
            get
            {
                return Finished ? "Finished" : RepositoryInfo.Commits.Count.ToString();
            }
        }
        public bool Finished { get; set; }
        public SvnCrawler (Repository repository)
        {
            Finished = false;
            DataSource = new DataClassesDataContext(@"Data Source=.\SQLEXPRESS;AttachDbFilename=" + repository.LocalLocation + @";Integrated Security=True;Connect Timeout=30;User Instance=True");
            var tempRepository = DataSource.Repositories.SingleOrDefault(r => r.Name == repository.Name);
            if (tempRepository == null)
            {
                RepositoryInfo = repository;
                DataSource.Repositories.InsertOnSubmit(RepositoryInfo);
                DataSource.SubmitChanges();
            }
            else
            {
                RepositoryInfo = tempRepository;
            }
            var client = new SvnClient();
            try
            {
                SvnInfoEventArgs info;
                client.GetInfo(RepositoryInfo.RemoteLocation, out info);
                LatestRevision = info.Revision;
            }
            catch (SvnInvalidNodeKindException e)
            {
                throw new Exception("No Svn found on given location.", e);
            }
        }

        public void FetchCommits()
        {
            //var tempRevision = DataSource.GetLatestCommit(RepositoryInfo.Name);
            //var startRevision = tempRevision.HasValue ? tempRevision.Value : 0;

            Parallel.For(0,
                         LatestRevision,
                         new ParallelOptions {MaxDegreeOfParallelism = 4},
                         (i) =>
                             {
                                 var downloader =
                                     new SvnDownloader(DataSource, RepositoryInfo, i + 1);
                                 downloader.FetchCommit();
                                 CommitFinished(downloader, EventArgs.Empty);
                             });
            Finished = true;
            //for (CurrentRevision = 1; CurrentRevision <= LatestRevision; CurrentRevision++)    
            //    FetchCommit(CurrentRevision);
        }

        

        public Commit GetCommit(long revision)
        {
            return RepositoryInfo.Commits.SingleOrDefault(r => r.Id == revision);
        }

        
    }
}
